--- /dev/null
+/*
+
+ Track reader for "Dell Axim Navigation System" GPB files,
+
+ Copyright (C) 2006 Olaf Klein, o.b.klein@t-online.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include "defs.h"
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define MYNAME "axim_gpb"
+
+#define RECORD_LEN 344
+
+static FILE *fin, *fout;
+static char dbginfo = 1;
+
+static
+arglist_t axim_gpb_args[] = {
+ ARG_TERMINATOR
+};
+
+static float
+le_read32_float(const void *src)
+{
+ float f;
+ gbint32 i;
+
+ i = le_read32(src);
+ memcpy(&f, &i, 4);
+
+ return f;
+}
+
+static void
+decode_buff(const char *buff, route_head *track)
+{
+ struct tm tm;
+ double lat, lon, alt, dir;
+ float vdop, hdop, pdop, spd, Uf1;
+ int sats;
+ waypoint *wpt;
+
+ wpt = waypt_new();
+
+ memset(&tm, '\0', sizeof(tm));
+
+ tm.tm_year = le_read16((void *) (buff + 16));
+ tm.tm_mon = le_read16((void *) (buff + 18));
+ tm.tm_mday = le_read16((void *) (buff + 22));
+ tm.tm_hour = le_read16((void *) (buff + 24));
+ tm.tm_min = le_read16((void *) (buff + 26));
+ tm.tm_sec = le_read16((void *) (buff + 28));
+
+ le_read64(&lat, (void *) (buff + 32));
+ le_read64(&lon, (void *) (buff + 40));
+ spd = le_read32_float((void *) (buff + 48));
+ dir = le_read32_float((void *) (buff + 52));
+
+ alt = le_read32_float((void *) (buff + 64));
+ Uf1 = le_read32_float((void *) (buff + 68));
+
+ hdop = le_read32_float((void *) (buff + 84));
+ vdop = le_read32_float((void *) (buff + 88));
+ pdop = le_read32_float((void *) (buff + 92));
+ sats = le_read16((void *) (buff + 96));
+
+ wpt->latitude = lat;
+ wpt->longitude = lon;
+ wpt->altitude = alt;
+#if 0
+ /* These values can be, but must not be right. */
+ /* Further checks are needed to verify that. */
+ /* (!!! reference data !!!) */
+ wpt->course = dir;
+ wpt->hdop = hdop;
+ wpt->vdop = vdop;
+ wpt->pdop = pdop;
+ wpt->sat = sats;
+ wpt->speed = spd * 10;
+#endif
+ /* We don't have a header with some magic fixed numbers or strings. */
+ /* So let us check the range for some basic values */
+
+ is_fatal(
+ (tm.tm_year < 2005) ||
+ (tm.tm_mon < 1) || (tm.tm_mon > 12) ||
+ (tm.tm_mday < 1) || (tm.tm_mday > 31) ||
+ (tm.tm_hour > 23) || (tm.tm_min > 60) || (tm.tm_sec > 60),
+ MYNAME ": Invalid or unsupported file (invalid time-stamp).");
+ is_fatal(
+ (fabs(wpt->latitude) > 180) ||
+ (fabs(wpt->longitude) > 90),
+ MYNAME ": Invalid or unsupported file (lat or/and lon out of range).");
+
+ /* post work */
+
+ tm.tm_year-=1900;
+ tm.tm_mon--;
+ wpt->creation_time = mkgmtime(&tm);
+
+ track_add_wpt(track, wpt);
+}
+
+/*******************************************************************************
+* %%% global callbacks called by gpsbabel main process %%% *
+*******************************************************************************/
+
+static void
+axim_gpb_rd_init(const char *fname)
+{
+ fin = xfopen(fname, "rb", MYNAME);
+}
+
+static void
+axim_gpb_rd_deinit(void)
+{
+ fclose(fin);
+}
+
+static void
+axim_gpb_read(void)
+{
+ char buff[RECORD_LEN];
+ route_head *track = NULL;
+ size_t bytes;
+ off_t filesize, left;
+
+ fseek(fin, 0, SEEK_END);
+ filesize = ftell(fin);
+
+ left = filesize - ((filesize / RECORD_LEN) * RECORD_LEN);
+ is_fatal((left != 0), MYNAME ": Invalid or unsupported file (filesize).");
+
+ fseek(fin, 0, SEEK_SET); /* seek file to start */
+
+ while ((bytes = fread(buff, 1, RECORD_LEN, fin)))
+ {
+ if (track == NULL)
+ {
+ track = route_head_alloc();
+ track_add_head(track);
+ }
+ decode_buff(buff, track);
+ }
+}
+
+/**************************************************************************/
+
+ff_vecs_t axim_gpb_vecs = {
+ ff_type_file,
+ {
+ ff_cap_none /* waypoints */,
+ ff_cap_read /* tracks */,
+ ff_cap_none /* routes */,
+ },
+ axim_gpb_rd_init,
+ NULL,
+ axim_gpb_rd_deinit,
+ NULL,
+ axim_gpb_read,
+ NULL,
+ NULL,
+ axim_gpb_args,
+ CET_CHARSET_ASCII, 0
+};
+/**************************************************************************/